home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 11799 < prev    next >
Encoding:
Text File  |  1996-08-05  |  5.7 KB  |  189 lines

  1. Newsgroups: comp.lang.c++
  2. Path: netcom.com!marnold
  3. From: marnold@netcom.com (Matt Arnold)
  4. Subject: Re: C++ Shortcomings ?
  5. Message-ID: <marnoldDoCpn0.Axu@netcom.com>
  6. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  7. References: <31488E8D.167E@aw.sgi.com> <4iaqch$moh@B1FF.mindspring.com> <31493CDA.41C6@aw.sgi.com>
  8. Date: Sat, 16 Mar 1996 08:16:11 GMT
  9. Sender: marnold@netcom2.netcom.com
  10.  
  11. Emmanuel Mogenet <mgix@aw.sgi.com> writes:
  12.  
  13. >Justin Rudd wrote:
  14. >> 
  15. >> Emmanuel Mogenet <mgix@aw.sgi.com> wrote:
  16. >> 
  17. >> >In other word, make portions of the interface to a class private to
  18. >> >only some classes.
  19. >> 
  20. >> >        1. Wouldn't that be nicer than the friend mechanism that cracks
  21. >> >           open a class a spill its guts ?
  22. >> >        2. Is there a clean way to achieve in today's C++ standard ?
  23. >> >        3. Or is it a bad idea altogether ?
  24. >> 
  25. >I guess my post was messy and unclear.
  26. >What I want is to be able for a class A to tell:
  27.  
  28.  
  29. >class A
  30. >{
  31. >restricted B:
  32. >    void    DoSomething();
  33. >}
  34.  
  35. >This means: Ok, the method A::DoSomething is public, but not
  36. >public for everybody. Only members of class B can have access to
  37. >this method.
  38.  
  39. >It's a bit like the friend operator, but instead of spilling
  40. >everything to the friend, we just let him peep through a specialized window.
  41.  
  42. Why not make a third "proxy" class C to represent the normally private parts 
  43. of A you would like B to have access to.
  44.  
  45. For example, say you have a class A with 10 private member functions.  You
  46. want B to access half of them without being able to access the other half.
  47. So, you make a class C that is a friend of A.  C has a pointer to some A
  48. and C's interface duplicates the half of A's interface you want to be
  49. "semi-public" (when C::SomeMember() is called, it simply forwards the 
  50. call to A::SomeMember()).  B, in turn, is a friend of C, so it can access
  51. C's interface.  This way, no one but B can call the select private members 
  52. of A (via C!).  And, B only has access to just those select members you 
  53. choose to make part of C's interface.
  54.  
  55. >> >2. Pointer type manipulation
  56. >> >-----------------------------
  57. >> 
  58. >> >A very disappointing thing in C++ (unless I am mistaken and it is actually
  59. >> >possible to do so) is the following situation:
  60. >> 
  61. >> >If A is a class, then most operations on A can be redefined.
  62. >> >Because A is a full blown type.
  63. >> 
  64. >> >Sadly, the same can not be said about A* (type: pointer to A).
  65. >> 
  66. >> >Even though A* is a type, none of its default manipulations
  67. >> >can be redefined.
  68. >> 
  69. >> >Example: You can tell C++, that you want to gain control of the
  70. >> >situation whenever an object of type A is duplicated.
  71. >> 
  72. >> >You do so by redefining the default copy constructor and the default
  73. >> >assignment operator.
  74. >> 
  75. >> >But can you tell C++ that you want to gain control whenever a pointer of
  76. >> >A* is duplicated ? Why can't I redefine the copy constructor for the type A* ?
  77.  
  78.  
  79. You can do this if you use a smart pointer for A (a class that acts like a
  80. pointer).  You smart pointer class can have any kind of overloading you like.
  81.  
  82. You cannot overload the literal type A*, of course.  Is this what you are
  83. complaining about?  If so, what is wrong with a smart pointer class?
  84.  
  85.  
  86. >> >In my way of looking at thing, that'd be a *great* way of doing clean reference
  87. >> >counting, instead of half-baked method using a redefinition of operator->.
  88. >>
  89.  
  90. What do you mean by half-baked?
  91.  
  92. >> >Comments ?
  93. >> 
  94. >> Ok...so you are saying you can do something like this...
  95.  
  96. >What I meant was: I would like to be able to redefine the default
  97. >copy constructor for pointers.
  98.  
  99. >In other words, when I write:
  100. >class A
  101. >{
  102. >};
  103.  
  104. >main()
  105. >{
  106. >    A    *a;
  107. >    B    *b;
  108.  
  109. >    a=new A();
  110. >    b=a;
  111. >}
  112.  
  113. >I want the compiler to trap this for me and give me control.
  114. >What I really want the compiler to do is:
  115.  
  116. >main()
  117. >{
  118. >    1. Call the constructor of object A* (that's what we do. We build an A*)
  119. >    2. Call the constructor of object B*
  120.  
  121. >    Call the constructor for object A* (to temporarily store the result of new)
  122. >    Call the assignment method (to assign the result of new to a)
  123. >    Call the assignment operator (to assign the value of a to b)
  124. >    
  125. >}
  126.  
  127. >Another way to put it:
  128. >I would like to be able to write
  129.  
  130. >class A*
  131. >{
  132. >    A*();        // To build a pointer to A
  133. >    A*(const A*&)    // To build an A* from another A*
  134. >    ~A*();        // To get hold of what happens when a pointer to A goes out of scope
  135.  
  136. >    A* operator=(const A*&);    // To redefine assignment
  137. >    
  138. >}
  139.  
  140.  
  141. >All this complicated mechanics would allow to build
  142. >industrial-strength reference counting on objects.
  143.  
  144.  
  145. You *can* build good reference counting on objects, with smart pointers.
  146. Assuming a properly implemented ref_ptr class, the code might look like 
  147. this...
  148.  
  149. main()
  150. {
  151.        ref_ptr<A> a;
  152.        ref_ptr<B> b;
  153.  
  154.        a=new A();
  155.        b=a;
  156. }
  157.  
  158. This syntax is pretty close to what you want.
  159.  
  160. Plus, somewhere, you get to write...
  161.  
  162.  
  163. template <class T>
  164. ref_ptr<T>& ref_ptr<T>::operator=(T* pt) 
  165.    {
  166.    // do assignment from a raw pointer however you like
  167.    }
  168.  
  169. template <class T>
  170. ref_ptr<T>& ref_ptr<T>::operator=(const ref_ptr<T>& pt)
  171.    {
  172.    // do assignment from another pointer object however you like
  173.    }
  174.  
  175.  
  176. The book "More Effective C++" has a pretty good discussion on reference
  177. counted objects with sample code for a reference-counted string class.  
  178. Smart pointers are also discussed.
  179.  
  180.  
  181. Regards,
  182. -------------------------------------------------------------------------
  183. Matt Arnold                       |        | ||| | |||| |  | | || ||
  184. marnold@netcom.com                |        | ||| | |||| |  | | || ||
  185. Boston, MA                        |      0 | ||| | |||| |  | | || ||
  186. 617.389.7384 (h) 617.576.2760 (w) |        | ||| | |||| |  | | || ||
  187. C++, MIDI, Win32/95 developer     |        | ||| 4 3 1   0 8 3 || ||
  188. -------------------------------------------------------------------------
  189.